//
//  LivingDetail_ViewController.m
//  MZSystem
//
//  Created by 智障 on 2018/11/5.
//  Copyright © 2018 zerod. All rights reserved.
//

#import "LivingDetail_ViewController.h"
#import "UIButton+Config.h"
#import "TimerManager.h"
#import "MZRateHud.h"
#import "MZChangeRateView.h"
#import "MZGlobleConfig.h"
#import <AVFoundation/AVFoundation.h>//调用闪光灯需要导入该框架
#import "MZLiveTopStataView.h"
#import "PLStreamingSessionConstructor.h"
#import "PLPermissionRequestor.h"
#import <PLMediaStreamingKit/PLMediaStreamingKit.h>
#import "UINavigationController+FDFullscreenPopGesture.h"
#define  iPhoneX (SCREEN_WIDTH == 375.f && SCREEN_HEIGHT == 812.f ? YES : NO)
@interface LivingDetail_ViewController ()<PLMediaStreamingSessionDelegate>

@property (nonatomic,strong) UIButton *backBtn;
@property (nonatomic,strong) UIButton *startLivingBtn;
@property (nonatomic,strong) UIButton *settingBtn;
@property (nonatomic,strong) UIButton *lightBtn;
@property (nonatomic,strong) UIButton *voiceBtn;
@property (nonatomic, strong) PLMediaStreamingSession *streamingSession;
@property (nonatomic,strong) MZLiveTopStataView *topStateView;
@property(nonatomic , strong) UIView *cameraPreviewView ;
@property (nonatomic,strong) UIView *contentView;
@property (nonatomic,assign) NSInteger lastValue;//上次码率
@property (nonatomic,strong) MZChangeRateView * rateView;
@property (nonatomic,assign) BOOL isHaveLiving;
@end

@implementation LivingDetail_ViewController
- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidAppear:YES];
     if (_streamingSession.isStreamingRunning) {
         [self.streamingSession destroy];
         [self.streamingSession stopStreaming];
         [self.cameraPreviewView removeFromSuperview];
         self.cameraPreviewView = nil;
     }
     [[TimerManager shareManager] pauseBtnClick];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillAppear:YES];
    [self setOrientationPortrait];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = RGB(81, 106, 248);
    UIView * contentView = [[UIView alloc]init];
    contentView.backgroundColor = [UIColor clearColor];
    [self.view addSubview:contentView];
    [contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(UIEdgeInsetsZero);
    }];
    self.contentView = contentView;
    
    
    self.fd_interactivePopDisabled = YES;
    [self setOrientationLandscape];
    [self initLivingEnv];
    [self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(@20);
        make.top.equalTo(@10);
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
    [self.settingBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(@(-20));
        make.bottom.equalTo(@(-30));
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
    [self.startLivingBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(@(-20));
        make.top.equalTo(@10);
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
    
    [self.topStateView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(@5);
        make.centerX.equalTo(self.view);
        make.height.equalTo(@40);
        make.width.equalTo(@320);
    }];
    [self.view addSubview:self.rateView];
    [self.rateView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.topStateView.mas_top).offset(0);
        make.left.equalTo(self.backBtn.mas_right).offset(5);
        make.height.mas_equalTo(40);
        make.width.mas_equalTo(ScrW/2 - 160 -60 - 5);
    }];
    [self checkAndMonitorBatteryLevel];
    //低于-85会出现掉格（不是满格），-70dbm左右属于挺好的，-60dbm左右属于信号很强
    if ([self getSignalStrength] < -85) {
        self.topStateView.signalState =  MZSignalStateWeak;
    }else if ([self getSignalStrength] >=85 && [self getSignalStrength] < 70){
        self.topStateView.signalState =  MZSignalStateMiddle;
    }else{
        self.topStateView.signalState =  MZSignalStateStrong;
    }
    [self didChangeBatteryLevel:nil];
    
}

//获取网络信号强度（dBm）
- (int)getSignalStrength{
    if (iPhoneX) {
        id statusBar = [[UIApplication sharedApplication] valueForKeyPath:@"statusBar"];
        id statusBarView = [statusBar valueForKeyPath:@"statusBar"];
        UIView *foregroundView = [statusBarView valueForKeyPath:@"foregroundView"];
        int signalStrength = 0;
        NSArray *subviews = [[foregroundView subviews][2] subviews];
        for (id subview in subviews) {
            if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]) {
                signalStrength = [[subview valueForKey:@"numberOfActiveBars"] intValue];
                break;
                
            }else if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")]) {
                signalStrength = [[subview valueForKey:@"numberOfActiveBars"] intValue]; break;
                
            }
            
        }
        return signalStrength;
        
    } else {
        UIApplication *app = [UIApplication sharedApplication];
        NSArray *subviews;
        // 不能用 [[self deviceVersion] isEqualToString:@"iPhone X"] 来判断，因为模拟器不会返回 iPhone X
        if ([[app valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
            subviews = [[[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
        } else {
            subviews = [[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
        }
//        NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
        NSString *dataNetworkItemView = nil;
        int signalStrength = 0;
        for (id subview in subviews) {
            if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]] && [[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
                dataNetworkItemView = subview;
                signalStrength = [[dataNetworkItemView valueForKey:@"_wifiStrengthBars"] intValue];
                break;
                
            } if ([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]] && ![[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
                dataNetworkItemView = subview;
                signalStrength = [[dataNetworkItemView valueForKey:@"_signalStrengthRaw"] intValue];
                break;
                
            }
            
        }
        return signalStrength;
    }
}

//检查当前是否连网
- (BOOL)whetherConnectedNetwork {
    //创建零地址，0.0.0.0的地址表示查询本机的网络连接状态
    struct sockaddr_storage zeroAddress;
    //IP地址
    bzero(&zeroAddress, sizeof(zeroAddress));
    //将地址转换为0.0.0.0
    zeroAddress.ss_len = sizeof(zeroAddress);
    //地址长度
    zeroAddress.ss_family = AF_INET;
    //地址类型为UDP, TCP, etc. // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    //获得连接的标志
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); CFRelease(defaultRouteReachability);
    //如果不能获取连接标志，则不能连接网络，直接返回
    if (!didRetrieveFlags) {
        return NO;
        
    }
    //根据获得的连接标志进行判断
    BOOL isReachable = flags & kSCNetworkFlagsReachable; BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired; return (isReachable&&!needsConnection) ? YES : NO;
    
}
//获取网络类型
- (NSString *)getNetworkType {
    if (![self whetherConnectedNetwork]) return @"NONE";
    UIApplication *app = [UIApplication sharedApplication];
    NSArray *subviews = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    NSString *type = @"NONE";
    for (id subview in subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
            int networkType = [[subview valueForKeyPath:@"dataNetworkType"] intValue];
            switch (networkType) {
                case 0: type = @"NONE";
                break;
                case 1: type = @"2G";
                break;
                case 2: type = @"3G";
                break; case 3: type = @"4G";
                break; case 5: type = @"WIFI";
                break;
                    
            }
            
        }
        
    }
    return type;
    
}

#pragma mark - 电池电量获取及监控
-(void)checkAndMonitorBatteryLevel{
    
    //拿到当前设备
    UIDevice * device = [UIDevice currentDevice];
    device.batteryMonitoringEnabled = true;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeBatteryLevel:) name:@"UIDeviceBatteryLevelDidChangeNotification" object:device];
    
}

- (void)didChangeBatteryLevel:(id)sender{
    //电池电量发生改变时调用
    UIDevice *myDevice = [UIDevice currentDevice];
    [myDevice setBatteryMonitoringEnabled:YES];
    float batteryLevel = [myDevice batteryLevel];
    if (batteryLevel < 0.25) {
        self.topStateView.energeState = MZEnergeStateWeak;
    }else if (batteryLevel >= 0.25 && batteryLevel < 0.5){
        self.topStateView.energeState = MZEnergeStateTwo;
    }else if (batteryLevel >= 0.5 && batteryLevel <0.75) {
        self.topStateView.energeState = MZEnergeStateThird;
    }else{
        self.topStateView.energeState = MZEnergeStateStrong;
    }
    NSLog(@"----------batteryLevel===%f",batteryLevel);
}
//初始化直播环境
- (void)initLivingEnv {
    PLVideoCaptureConfiguration *videoCaptureConfiguration = [PLVideoCaptureConfiguration defaultConfiguration];
    videoCaptureConfiguration.videoFrameRate = [MZGlobleConfig defaultManager].videoFrameRate;
    
    PLVideoStreamingConfiguration *videoStreamingConfiguration = [PLVideoStreamingConfiguration defaultConfiguration];
    videoStreamingConfiguration.videoSize = [MZGlobleConfig defaultManager].videoSize;
    //当 audioCaptureConfiguration 或 audioStreamingConfiguration 为 nil
    PLAudioCaptureConfiguration *audioCaptureConfiguration = [PLAudioCaptureConfiguration defaultConfiguration];
    PLAudioStreamingConfiguration *audioStreamingConfiguration = [PLAudioStreamingConfiguration defaultConfiguration];
    
    _streamingSession = [[PLMediaStreamingSession alloc] initWithVideoCaptureConfiguration:videoCaptureConfiguration audioCaptureConfiguration:audioCaptureConfiguration videoStreamingConfiguration:videoStreamingConfiguration audioStreamingConfiguration:audioStreamingConfiguration stream:nil];
    [_streamingSession enableAdaptiveBitrateControlWithMinVideoBitRate:[MZGlobleConfig defaultManager].videoBitRate];
    _streamingSession.delegate = self;
    __weak typeof(self) weakSelf = self;
    PLPermissionRequestor *permission = [[PLPermissionRequestor alloc] init];
    permission.noPermission = ^{};
    permission.permissionGranted = ^{
        if (!self->_cameraPreviewView) {
            self.cameraPreviewView = weakSelf.streamingSession.previewView;
            weakSelf.streamingSession.videoOrientation = [UIApplication sharedApplication].statusBarOrientation;
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.contentView insertSubview:self.cameraPreviewView atIndex:0];
                [self.cameraPreviewView mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.top.bottom.left.and.right.equalTo(self.contentView);
                }];
            });
        }
    };
    [permission checkAndRequestPermission];
}

- (void)startToLive {
    if (!_streamingSession.isStreamingRunning) {
        if (!_pushUrl) {
            return;
        }
        [self startStreaming];
        [self.view sendSubviewToBack:self.cameraPreviewView];
    }
}
//开始推流 或者重试
- (void) startStreaming {
     [_streamingSession startStreamingWithPushURL:[NSURL URLWithString:self.pushUrl] feedback:^(PLStreamStartStateFeedback feedback) {
         if (feedback == PLStreamStartStateSuccess) {
             self.startLivingBtn.selected = YES;
             self.isHaveLiving = YES;
         } else {
             
         }
     }];
}

// MARK: 会话代理方法
/// @abstract 流状态已变更的回调
 - (void)mediaStreamingSession:(PLMediaStreamingSession *)session streamStateDidChange:(PLStreamState)state {
     if (state == PLStreamStateConnected) {
        
         [[TimerManager shareManager] startBtnClick:^(NSString *currentString) {
             //低于-85会出现掉格（不是满格），-70dbm左右属于挺好的，-60dbm左右属于信号很强
             if ([self getSignalStrength] < -85) {
                 self.topStateView.signalState =  MZSignalStateWeak;
             }else if ([self getSignalStrength] >=85 && [self getSignalStrength] < 70){
                 self.topStateView.signalState =  MZSignalStateMiddle;
             }else{
                 self.topStateView.signalState =  MZSignalStateStrong;
             }
             self.topStateView.time = currentString;
         }];
     }
}

/// @abstract 因产生了某个 error 而断开时的回调，error 错误码的含义可以查看 PLTypeDefines.h 文件
 - (void)mediaStreamingSession:(PLMediaStreamingSession *)session didDisconnectWithError:(NSError *)error {
     NSLog(@"didDisconnectWithError == %@",error);
     [SVProgressHUD showErrorWithStatus:error.userInfo[@"NSLocalizedDescription"]];

 }

/// @abstract 当开始推流时，会每间隔 3s 调用该回调方法来反馈该 3s 内的流状态，流的实时状态信息 :包括视频帧率、音频帧率、音视频总码率

 - (void)mediaStreamingSession:(PLMediaStreamingSession *)session streamStatusDidUpdate:(PLStreamStatus *)status {
     if (self.lastValue != session.videoStreamingConfiguration.averageVideoBitRate) {
         NSUInteger realRate = session.videoStreamingConfiguration.averageVideoBitRate/1000;
         [[MZRateHud defaultRate] showWithTitle:[NSString stringWithFormat:@"%lukbps",(unsigned long)realRate] withFrame:CGRectMake(CGRectGetMidX(self.view.frame) - 90, 45, 180, 30)];
         self.lastValue = session.videoStreamingConfiguration.averageVideoBitRate;
     }     
 }

/// @abstract 因产生了某个 error 的回调，error 错误码的含义可以查看 PLTypeDefines.h 文件

 - (void)mediaStreamingSession:(PLMediaStreamingSession *)session rtcDidFailWithError:(NSError *)error {
     NSLog(@"rtcDidFailWithError == %@",error);
     [SVProgressHUD showErrorWithStatus:error.userInfo[@"NSLocalizedDescription"]];
}

- (UIButton *)backBtn {
    if (_backBtn == nil) {

        __weak typeof(self) weakSelf = self;
        _backBtn = UIButton
        .byd_buttonType(UIButtonTypeCustom)
        .byd_image([UIImage imageNamed:@"播放器 退出"],UIControlStateNormal)
        .byd_image([UIImage imageNamed:@"播放器 关闭"],UIControlStateSelected)
        .byd_addParamActionHandle(UIControlEventTouchUpInside,^(UIButton *sender){
            if (sender.selected == NO) {
                if (weakSelf.streamingSession.isStreamingRunning) {
                    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"" message:@"是否不发布直接关闭" preferredStyle:UIAlertControllerStyleAlert];
                    UIAlertAction * cancleact = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
                    UIAlertAction * sureact = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                        [MZRateHud defaultRate].hidden = YES;
                        [weakSelf.streamingSession destroy];
                        [weakSelf.streamingSession stopStreaming];
                        [[TimerManager shareManager] pauseBtnClick];
                        [self.cameraPreviewView removeFromSuperview];
                        self.cameraPreviewView = nil;
                        [weakSelf.navigationController popViewControllerAnimated:NO];
                    }];
                    [alert addAction:cancleact];
                    [alert addAction:sureact];
                    [self presentViewController:alert animated:YES completion:nil];
                }else{
                    [MZRateHud defaultRate].hidden = YES;
                    [weakSelf.streamingSession destroy];
                    [weakSelf.streamingSession stopStreaming];
                    [[TimerManager shareManager] pauseBtnClick];
                    [self.cameraPreviewView removeFromSuperview];
                    self.cameraPreviewView = nil;
                    [weakSelf.navigationController popViewControllerAnimated:NO];
                }
                
            }else{
                sender.selected = NO;
                self.rateView.hidden = !self.rateView.hidden;
            }
        })
        ;
        [self.contentView addSubview:_backBtn];
    }
    return _backBtn;
}

- (void)settingOpen {
    [self.lightBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.settingBtn.mas_left).offset(-40);
        make.bottom.equalTo(@(-30));
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
    [self.voiceBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.lightBtn.mas_left).offset(-20);
        make.bottom.equalTo(@(-30));
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
}
- (void)settingClose {
    [self.lightBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_right);
        make.bottom.equalTo(@(-30));
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
    [self.voiceBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_right);
        make.bottom.equalTo(@(-30));
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
}

- (UIButton *)startLivingBtn {
    if (_startLivingBtn == nil) {
        __weak typeof(self) weakSelf = self;
        _startLivingBtn = UIButton
        .byd_buttonType(UIButtonTypeCustom)
        .byd_image([UIImage imageNamed:@"播放器 开始直播"],UIControlStateNormal)
        .byd_image([UIImage imageNamed:@"播放器 关闭直播"],UIControlStateSelected)
        .byd_addParamActionHandle(UIControlEventTouchUpInside,^(UIButton *sender){
            
            if (sender.selected == NO) {
                if (self.isHaveLiving) {
                    [self.streamingSession restartStreamingWithFeedback:^(PLStreamStartStateFeedback feedback) {
                        if (feedback == PLStreamStartStateSuccess) {
                            self.startLivingBtn.selected = YES;
                            self.isHaveLiving = YES;
                        } else {

                        }
                    }];
                }else{
                    [self startToLive];
                }
            }else{
                sender.selected = NO;
                [weakSelf.streamingSession stopStreaming];
                [[TimerManager shareManager] pauseBtnClick];
            }
        })
        ;
        [self.contentView addSubview:_startLivingBtn];
    }
    return _startLivingBtn;
}
- (UIButton *)settingBtn {
    if (_settingBtn == nil) {
        _settingBtn = UIButton
        .byd_buttonType(UIButtonTypeCustom)
        .byd_image([UIImage imageNamed:@"播放器 设置"],UIControlStateNormal)
        .byd_image([UIImage imageNamed:@"播放器 设置"],UIControlStateSelected)
        .byd_addParamActionHandle(UIControlEventTouchUpInside,^(UIButton *sender){
            sender.selected = !sender.selected;
            if (sender.selected == YES) {
                [self settingOpen];
            }else{
                [self settingClose];
            }
        })
        ;
        [self.contentView addSubview:_settingBtn];
    }
    return _settingBtn;
}
- (UIButton *)lightBtn {
    if (_lightBtn == nil) {
        _lightBtn = UIButton
        .byd_buttonType(UIButtonTypeCustom)
        .byd_image([UIImage imageNamed:@"闪光 copy"],UIControlStateNormal)
        .byd_image([UIImage imageNamed:@"播放器 上光灯"],UIControlStateSelected)
        .byd_addParamActionHandle(UIControlEventTouchUpInside,^(UIButton *sender) {
            sender.selected = !sender.selected;
            if (sender.isSelected == YES) { //打开闪光灯
                AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
                NSError *error = nil;
                
                if ([captureDevice hasTorch]) {
                    BOOL locked = [captureDevice lockForConfiguration:&error];
                    if (locked) {
                        captureDevice.torchMode = AVCaptureTorchModeOn;
                        [captureDevice unlockForConfiguration];
                    }
                }
            }else{//关闭闪光灯
                AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
                if ([device hasTorch]) {
                    [device lockForConfiguration:nil];
                    [device setTorchMode: AVCaptureTorchModeOff];
                    [device unlockForConfiguration];
                }
            }
        })
        ;
        [self.contentView addSubview:_lightBtn];
    }
    return _lightBtn;
}
- (UIButton *)voiceBtn {
    if (_voiceBtn == nil) {
        _voiceBtn = UIButton
        .byd_buttonType(UIButtonTypeCustom)
        .byd_image([UIImage imageNamed:@"播放器 声音开"],UIControlStateNormal)
        .byd_image([UIImage imageNamed:@"播放器 声音"],UIControlStateSelected)
        .byd_addParamActionHandle(UIControlEventTouchUpInside,^(UIButton *sender){
            sender.selected = !sender.selected;
            if (sender.selected) {
                self.streamingSession.muteMicrophone = YES;
            }else{
                self.streamingSession.muteMicrophone = NO;
            }
        })
        ;
        [self.contentView addSubview:_voiceBtn];
    }
    return _voiceBtn;
}

- (MZLiveTopStataView *)topStateView {
    if (_topStateView == nil) {
        _topStateView = [[[NSBundle mainBundle] loadNibNamed:@"MZLiveTopStataView" owner:self options:nil]firstObject];
        _topStateView.backgroundColor = RGBA(0, 0, 0, 0.4);
        __weak typeof(self) wealkSelf = self;
        _topStateView.showRateBlock = ^{
            wealkSelf.rateView.hidden = !wealkSelf.rateView.hidden ;;
            wealkSelf.backBtn.selected = !wealkSelf.backBtn.selected;
        };
        [self.contentView addSubview:_topStateView];
        
    }
    return _topStateView;
}
-(MZChangeRateView *)rateView{
    if (!_rateView) {
        _rateView = [[[NSBundle mainBundle]loadNibNamed:@"MZChangeRateView" owner:self options:nil] firstObject];
        _rateView.backgroundColor = RGBA(0, 0, 0, 0.4);
        _rateView.tag = 1000;
        _rateView.hidden=YES;
        WS(weakSelf)
        _rateView.mzRateBlock = ^(NSInteger rate) {
            [weakSelf.streamingSession enableAdaptiveBitrateControlWithMinVideoBitRate:rate];
        };
    }
    return _rateView;
}

// MARK: 懒加载直播
- (UIView *)cameraPreviewView {
    if (_cameraPreviewView == nil) {
        _cameraPreviewView = [[UIView alloc]init];;
        [self.view addSubview:_cameraPreviewView];
    }
    return _cameraPreviewView;
}
@end
